package com.yytek.am.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.yytek.am.constants.AkkaConstants;
import com.yytek.am.constants.MessageType;
import com.yytek.am.core.runtime.EventRuleActor;
import com.yytek.am.domain.*;
import com.yytek.am.dto.AmRuleData;
import com.yytek.am.mapper.*;
import com.yytek.common.client.base.MqMessage;
import com.yytek.common.client.net.IotMqttClient;
import com.yytek.common.web.domain.CollectInfo;
import com.yytek.common.web.domain.ProCommonMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 告警规则处理Service业务层处理
 * 
 * @author yytek-iot
 * @date 2022-10-10
 */
@Service
public class AmRuleHandleServiceImpl
{
    @Autowired
    private FmDefMapper fmDefMapper;
    @Autowired
    private FmRuleGenerateMapper ruleGenerateMapper;
    @Autowired
    private FmRuleClearMapper ruleClearMapper;
    @Autowired
    private FmEventRecordMapper eventRecordMapper;
    @Autowired
    private FmEventMapper eventMapper;
    @Autowired
    private FmEventHisMapper fmEventHisMapper;
    @Resource
    IotMqttClient iotMqttClient;
    /**
     * 通过规则引擎处理属性数据
     * @param line
     */
    public void handleAmMqttMsg(MqMessage line){
        String msg = new String(line.getPayload());
        //解析line中换成接收的参数实体
        ProCommonMessage sendData = JSON.parseObject
                (msg,ProCommonMessage.class);
        //解析数据到规则引擎处理
        try {
            paraseDataToRule(sendData);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 解析数据到规则引擎处理
     * @param sendData
     */
    public void paraseDataToRule(ProCommonMessage sendData) throws Exception {
        //设备数据
        Map<String, CollectInfo> params = sendData.getParams();
        //设备Id
        String iotId = sendData.getDeviceId();
        //设备处理数据列表
        List<AmRuleData> fields = new ArrayList<>();
        if(params != null){
            //添加属性值到属性数据列
            for(Map.Entry entry : params.entrySet()){
                AmRuleData field = new AmRuleData();
                field.setDeviceName(iotId);
                field.setKpiName(entry.getKey().toString());
                CollectInfo collectInfo = params.get(entry.getKey().toString());
                field.setKpiValue(collectInfo.getValue());
                fields.add(field);
            }
            //规则引擎处理属性数据
            handleRuleDatas(fields);
        }
    }

    /**
     * 处理属性数据列到告警规则
     * @param fields
     */
    public void handleRuleDatas(List<AmRuleData> fields) throws Exception {
        if(CollectionUtil.isNotEmpty(fields)){
            for (int i = 0; i < fields.size(); i++) {
                AmRuleData ruleData = fields.get(i);
                //处理告警源数据到akka处理计算
                handleSourceDataToAkka(ruleData);
            }
        }

    }

    /**
     * 处理告警源数据到akka处理计算
     * @param ruleData
     */
    public void handleSourceDataToAkka(AmRuleData ruleData) {
        //处理成 InputData 字段 kpiName  kpiValue deviceName productName的jsonObject格式
        String jsonStr = JSON.toJSONString(ruleData);
        //发送到akka的mqtt
        iotMqttClient.publish(MessageType.AM_ALARM_SOURCE,jsonStr);
    }



    /**
     * 处理akka返回符合告警规则数据
     * @param msg
     */
    public void handleAkkaMqttMsg(MqMessage msg) {
        //返回数据记录数据
        EventRuleActor.EventRecord record =JSON.parseObject(msg.getPayload(),
                EventRuleActor.EventRecord.class);
        //查询公用指定告警定义
        FmDef fmDef = fmDefMapper.selectFmDefById(record.getAlarmDefineId());
        //设置serchindex为设备id
        String deviceId = record.getSearchIndex().split("_")[1];
        record.setSearchIndex(deviceId);
        //根据类型写入不同记录
        if(record.getType().intValue() == AkkaConstants.EventType.ALARM_CLEAR){
            //清除记录
            insertAmEventHis(record,fmDef);
        }else if(record.getType().intValue() == AkkaConstants.EventType.ALARM_GENERATE){
            //生成记录
            insertAmEvent(record,fmDef);
        }
        //统一记录原始记录
        insertAmRecord(record,fmDef);
    }

    /**
     * 生成告警活动记录
     * @param record
     * @param fmDef
     */
    private void insertAmEvent(EventRuleActor.EventRecord record, FmDef fmDef) {
        FmEvent fmEvent = new FmEvent();
        fmEvent.setProjectId(fmDef.getProjectId());
        fmEvent.setAlarmDefineId(fmDef.getId());
        fmEvent.setLabel(fmDef.getLabel());
        fmEvent.setLevel(fmDef.getLevel());
        fmEvent.setTitle(fmDef.getTitle());
        fmEvent.setContent(fmDef.getContent());
        fmEvent.setSearchIndex(record.getSearchIndex());
        fmEvent.setAccCount(Long.valueOf(record.getAccCount()));
        fmEvent.setAckFlag(Long.valueOf(0l));
        Date createDate = new Date(record.getCreateTime());
        fmEvent.setCreateTime(createDate);
        Date updateDate = new Date(record.getUpdateTime());
        fmEvent.setUpdateTime(updateDate);
        eventMapper.insertFmEvent(fmEvent);
    }

    /**
     * 生成告警历史记录
     * @param record
     * @param fmDef
     */
    private void insertAmEventHis(EventRuleActor.EventRecord record, FmDef fmDef) {
        //复制活动告警到历史告警
        FmEventHis fmEventHis = new FmEventHis();
        fmEventHis.setAlarmDefineId(fmDef.getId());
        fmEventHis.setProjectId(fmDef.getProjectId());
        fmEventHis.setLabel(fmDef.getLabel());
        fmEventHis.setLevel(fmDef.getLevel());
        fmEventHis.setTitle(fmDef.getTitle());
        fmEventHis.setContent(fmDef.getContent());
        fmEventHis.setSearchIndex(record.getSearchIndex());
        fmEventHis.setAccCount(Long.valueOf(record.getAccCount()));
        //未确认状态
        fmEventHis.setAckFlag(0);
        //设置清除时间和清除人
        Date date = new Date();
        fmEventHis.setClearTime(date);
        fmEventHis.setCreateTime(date);
        String userId = "system";
        fmEventHis.setClearOperator(userId);
        fmEventHis.setClearNote("根据清除规则系统自动清除");
        fmEventHisMapper.insertFmEventHis(fmEventHis);
    }

    /**
     * 根据akka记录生成原始记录
     *
     * @param record
     * @param fmDef
     */
    public void insertAmRecord(EventRuleActor.EventRecord record, FmDef fmDef) {
        FmEventRecord eventRecord = new FmEventRecord();
        eventRecord.setAlarmDefineId(record.getAlarmDefineId());
        eventRecord.setProjectId(fmDef.getProjectId());
        eventRecord.setKpiName(record.getKpiName());
        eventRecord.setKpiValue(record.getKpiValue());
        eventRecord.setSearchIndex(record.getSearchIndex());
        eventRecord.setCreateTime(new Date(record.getCreateTime()));
        eventRecordMapper.insertFmEventRecord(eventRecord);
    }
}
